/**
 * \file vector3_usage.cpp
 * 
 * \section COPYRIGHT
 *
 * Basis: A 3D Mathematics Library
 *
 * ---------------------------------------------------------------------
 *
 * Copyright (c) 2010, Don Olmstead
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *
 *  3. Neither the name of organization nor the names of its contributors may be
 *     used to endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// Include STL libraries
#include <iostream>

// Include the mathematics classes
#include <basis/scalar.hpp>
#include <basis/vector3.hpp>

// Include the SIMD interfaces
#include <basis/detail/packed_type.hpp>
#include <basis/detail/sse_type.hpp>

//------------------------------------------------------------
// Configuration options
//------------------------------------------------------------

// Set the real number type to use
typedef float real_type;

// Set the SIMD type to use
typedef basis::detail::packed_type<real_type> simd_type;

// Set the vector3 type to use
typedef basis::vector3<real_type, simd_type> vector3_type;

int main(int argc, char* argv[])
{
	vector3_type a((real_type)1, (real_type)2, (real_type)3);
	vector3_type b((real_type)5, (real_type)6, (real_type)7);

	std::cout << "A = " << a << std::endl;
	std::cout << "B = " << b << std::endl << std::endl;

	// Show mathematical operations
	std::cout << "A + B = " << a + b << std::endl;
	std::cout << "A - B = " << a - b << std::endl;
	std::cout << "A * B = " << a * b << std::endl;
	std::cout << "A / B = " << a / b << std::endl << std::endl;

	// Show comparison operations
	std::cout << "A == A is " << ((a == a) ? "true" : "false") << std::endl;
	std::cout << "A == B is " << ((a == b) ? "true" : "false") << std::endl;
	std::cout << "A != A is " << ((a != a) ? "true" : "false") << std::endl;
	std::cout << "A != B is " << ((a != b) ? "true" : "false") << std::endl << std::endl;

	// Show min/max operations
	std::cout << "min(A, B) = " << vector3_type::min(a, b) << std::endl;
	std::cout << "max(A, B) = " << vector3_type::max(a, b) << std::endl << std::endl;

	// Show vector operations
	std::cout << "length(A) = " << a.length() << std::endl;
	std::cout << "length(B) = " << b.length() << std::endl;
	std::cout << "normal(A) = " << vector3_type::normalize(a) << std::endl;
	std::cout << "normal(B) = " << vector3_type::normalize(b) << std::endl;
	std::cout << "dot(A, B) = " << vector3_type::dot(a, b) << std::endl;
	std::cout << "distance(A, B) = " << vector3_type::distance(a, b) << std::endl << std::endl;

	// Show shuffle operations
	std::cout << "A.xyz = " << a.xyz << std::endl;
	std::cout << "A.yzx = " << a.yzx << std::endl;
	std::cout << "A.zxy = " << a.zxy << std::endl;

	// Show special vectors
	std::cout << "unit(x) = " << vector3_type::unit_x() << std::endl;
	std::cout << "unit(y) = " << vector3_type::unit_y() << std::endl;
	std::cout << "unit(z) = " << vector3_type::unit_z() << std::endl;
}
